﻿ ניהול תבניות ועיצוב
=======

תבנית הינה דרך שיטתית לשינוי התצוגה של העמודים באפליקצית ווב. על ידי הוספת תבנית חדשה, המראה הכללי של האפליקציה משתנה באופן מיידי ודרמטי.

ב Yii, כל תבנית מיוצגת כתיקיה המכילה קבצי תצוגה, קבצי תבנית, קבצי סקריפט (Js, CSS), תמונות, וכדומה. שם התבנית הוא שם התיקיה בה הוא נמצא. כל התבניות נמצאות תחת אותה תיקיה `WebRoot/themes`. בכל זמן נתון, רק תבנית אחת יכולה להיות פעילה.

> Tip|טיפ: תיקית התבניות ברירת המחדל `WebRoot/themes` ניתנת לשינוי לתיקיה אחרת בשרת. בכדי לבצע זאת יש להגדיר את המאפיינים [basePath|CThemeManager::basePath] ו [baseUrl|CThemeManager::baseUrl] של רכיב האפליקציה [themeManager|CWebApplication::themeManager].

בכדי להפעיל תבנית, יש להגדיר את המאפיין [theme|CWebApplication::theme] של האפליקציה לשם התבנית הרצוי שבו רוצים להשתמש. ניתן לבצע הגדרה זו בקובץ [הגדרות](/doc/guide/basics.application#application-configuration) האפליקציה או במהלך הרצת האפליקציה בפעולות בקונטרולר.

> Note|הערה: שמות התבניות רגישות לאותיות גדולות-קטנות. אם יהיה ניסיון להפעיל תבנית אשר אינה קיימת, שימוש ב `Yii::app()->theme` יחזיר null.

התכנים הנמצאים בתיקית תבנית צריכים להיות מאורגנים באותה צורה כמו אלו הנמצאים תחת התיקיה [הראשית](/doc/guide/basics.application#application-base-directory) של האפליקציה. לדוגמא, כל קבצי התצוגה צריכים להמצא תחת התיקיה `views`, קבצי תבניות צריכים להמצא תחת התיקיה `views/layouts`, וקבצי תצוגה מערכתיים צריכים להמצא תחת התיקיה `views/system`. לדוגמא, אם אנו רוצים להחליף את קובץ התצוגה `create` השייך לקונטרולר `PostController` עם קובץ התצוגה של התבנית `classic`, אנו צריכים לשמור את קובץ התצוגה החדש תחת התיקיה `WebRoot/themes/classic/views/post/create.php`.

עבור קבצי תצוגה השייכים לקונטרולר הנמצא בתוך [מודול](/doc/guide/basics.module) מסויים, קבצי התצוגה המקבילים צריכים גם הם להיות ממקומים תחת התיקיה `views`. לדוגמא, אם קובץ הקונטרולר הנ"ל `PostController` נמצא תחת מודול בשם `forum`, אנו צריכים לשמור את קובץ התצוגה `create` שהוא משתמש בו כ `WebRoot/themes/classic/views/forum/post/create.php`. במידה והמודול `forum` נמצא תחת מודול נוסף בשם `support`, אז אנו נשמור את קובץ התצוגה הנ"ל כ `WebRoot/themes/classic/views/support/forum/post/create.php`.

> Note|הערה: מאחר ותיקית קבצי התצוגה `views` יכולה להכיל מידע הרגיש מבחינת אבטחה, היא צריכה להיות מוגדרת כתיקיה שלא ניתן לצפות בתוכנה על ידי משתמשי הקצה.

כשאנו נשתמש במתודות [render|CController::render] או [renderPartial|CController::renderPartial] בכדי להציג קובץ תצוגה, קובץ התצוגה הנ"ל וקובץ התבנית יטענו מהתיקיה של התבנית הנמצאת בשימוש כרגע. במידה והם נמצאו, קבצים אלו יוצגו. במידה ולא, קבצי התצוגה נסוגו לנתיב ברירת המחדל שלהם תחת [viewPath|CController::viewPath] ו [layoutPath|CWebApplication::layoutPath].

> Tip|טיפ: בתוך קובץ תצוגה, אנו בדרך כלל צריכים לטעון משאבים (תמונות, קבצי סקריפט) מאותה תיקיה של התבנית בה אנו משתמשים כרגע. לדוגמא, אנו רוצים להציג תמונה הנמצאת בתיקיה `images` תחת התיקיה של התבנית הפעילה כרגע. שימוש במאפיין [baseUrl|CTheme::baseUrl] של התבנית הפעילה כרגע, אנו יכולים ליצור קישור לתמונה בצורה הבאה,
>
> ~~~
> [php]
> Yii::app()->theme->baseUrl . '/images/FileName.gif'
> ~~~
>

להלן דוגמא לארגון תיקיות של אפליקציה המשתמשת בשני תבניות `basic` ו `fancy`.

~~~
WebRoot/
    assets
    protected/
        .htaccess
        components/
        controllers/
        models/
        views/
            layouts/
                main.php
            site/
                index.php
    themes/
        basic/
            views/
                .htaccess
                layouts/
                    main.php
                site/
                    index.php
        fancy/
            views/
                .htaccess
                layouts/
                    main.php
                site/
                    index.php
~~~

בהגדרות האפליקציה, אם נגדיר

~~~
[php]
return array(
    'theme'=>'basic',
    ......
);
~~~

אז התבנית `basic` תיהיה פעילה, אשר אומר שקובץ תבנית האפליקציה יטען מהתיקיה `themes/basic/views/layouts`, וקובץ התצוגה `index` יטען מהנתיב `themes/basic/views/site`. במידה וקובץ תצוגה לא נמצא בתבנית, האפליקציה תסוג לקובץ התצוגה הנמצא תחת התיקיה `protected/views`.


התאמה גלובאלית לוידג'טים
----------------------------

> Note|הערה: אפשרות זו קיימת החל מגרסא 1.1.3.

בעת השימוש בוידג'ט שסופק על ידי Yii או גורם צד שלישי, אנו בדרך כלל צריכים להתאים אותו לדרישות הספציפיות שלנו. לדוגמא, אנו נרצה לשנות את ערך ברירת המחדל של [CLinkPager::maxButtonCount] מ 10 כברירת מחדל ל 5. אנו יכולים לבצע זאת על ידי הצבת פרמטר בעת הקריאה ל-[CBaseController::widget] בעת יצירת הוידג'ט. אך דרך זו הופכת להיות טרחה מאחר ואנו חוזרים על אותו הפעולה שוב ושוב במקומות שונים באפליקציה בכל מקום בו אנו משתמשים ב-[CLinkPager].

~~~
[php]
$this->widget('CLinkPager', array(
    'pages'=>$pagination,
    'maxButtonCount'=>5,
    'cssFile'=>false,
));
~~~

בעזרת שימוש בהגדרות גלובאליות לוידג'טים, אנו צריכים להגדיר את הערכים הללו במקום אחד בלבד, לדוגמא, קובץ הגדרות האפליקציה. פעולה זו הופכת את ניהול ותחזוקת הוידג'טים לקלה יותר.

בכדי להשתמש באפשרות של הגדרות גלובאליות עבור וידג'טים, אנו צריכים להגדיר את [widgetFactory|CWebApplication::widgetFactory] בצורה הבאה:

~~~
[php]
return array(
    'components'=>array(
        'widgetFactory'=>array(
            'widgets'=>array(
                'CLinkPager'=>array(
                    'maxButtonCount'=>5,
                    'cssFile'=>false,
                ),
                'CJuiDatePicker'=>array(
                    'language'=>'ru',
                ),
            ),
        ),
    ),
);
~~~

בקוד המוצג למעלה, אנו מגדירים את ההגדרות הגלובאליות עבור הוידג'טים [CLinkPager] ו [CJuiDatePicker] על ידי הגדרת המאפין [CWidgetFactory::widgets]. יש לזכור שהגדרות גלובאליות עבור כל וידג'ט מיוצגות כמפתח->ערך במערך, כשהמפתח מייצג את שם המחלקה של הוידג'ט והערך מייצג מערך של הגדרות גלובאליות לוידג'ט.

כעת, בכל פעם שאנו ניצור וידג'ט [CLinkPager] בקובץ תצוגה, המאפיינים המוגדרים למעלה יוצבו כברירת מחדל לוידג'ט, וכל מה שאנו צריכים כדי ליצור את הוידג'ט הוא לכתוב את הקוד הבא:

~~~
[php]
$this->widget('CLinkPager', array(
    'pages'=>$pagination,
));
~~~

אנו תמיד יכולים לדרוס את ההגדרות הגלובלאיות בעת הצורך. לדוגמא, אם בקובץ תצוגה כלשהו אנו נרצה להגדיר את המאפיין `maxButtonCount` ל-2, אנו יכולים לבצע את זאת בעזרת הקוד הבא:

~~~
[php]
$this->widget('CLinkPager', array(
    'pages'=>$pagination,
    'maxButtonCount'=>2,
));
~~~


עיצוב
----

> Note|הערה: אפשרות העיצוב קיימת החל מגרסא 1.1.0.

בזמן שאנו משתמשים בתבנית בכדי לשנות את המראה החיצוני של האפליקציה, אנו יכולים להשתמש בעיצובים בכדי לשנות את עיצוב [הוידג'טים](/doc/guide/basics.view#widget) הנמצאים בתוך קבצי התצוגה.

עיצוב הוא מערך של אלמנטים שבעזרתו ניתן לאתחל מאפיינים של וידג'ט. עיצוב שייך למחלקה של וידג'ט, ומחלקה של וידג'ט יכולה להכיל כמה עיצובים המזוהים על פי שמותיהם. לדוגמא, אנו יכולים להגדיר עיצוב לוידג'ט [CLinkPager] ושמו של העיצוב הוא `classic`.

בכדי להשתמש באפשרות של העיצובים, אנו קודם צריכים לערוך את הגדרות האפליקציה על ידי התקנת הרכיב `widgetFactory`:

~~~
[php]
return array(
    'components'=>array(
        'widgetFactory'=>array(
            'enableSkin'=>true,
        ),
    ),
);
~~~

זכור שבגרסאות קודמות ל 1.1.3, בכדי להשתמש בעיצובים עבור וידג'טים יש צורך להשתמש בקוד הבא:

~~~
[php]
return array(
    'components'=>array(
        'widgetFactory'=>array(
            'class'=>'CWidgetFactory',
        ),
    ),
);
~~~

לאחר מכן אנו יוצרים את העיצובים הדרושים. עיצובים השייכים לאותו מחלקת וידג'ט נשמרים בקובץ PHP אחד ששמו הוא שם המחלקה של הוידג'ט. כל קבצי העיצובים הללו נשמרים תחת `protected/views/skins`, כברירת מחדל. במידה ויש צורך לשנות מיקום זה לתיקיה אחרת, ניתן להגדיר את המאפיין `skinPath` של הרכיב `widgetFactory`. לדוגמא, אנו יכולים ליצור תחת התיקיה `protected/views/skins` קובץ בשם `CLinkPage.php` שתוכנו הוא הקוד הבא,

~~~
[php]
<?php
return array(
    'default'=>array(
        'nextPageLabel'=>'&gt;&gt;',
        'prevPageLabel'=>'&lt;&lt;',
    ),
    'classic'=>array(
        'header'=>'',
        'maxButtonCount'=>5,
    ),
);
~~~

בקוד המוצג למעלה, אנו יוצרים שני עיצובים עבור הוידג'ט [CLinkPager] והם `default` ו `classic`. הראשון הוא העיצוב שיצורף לכל אובייקט של הוידג'ט [CLinkPager] שאנו לא מגדירים את המאפיין `skin` באובייקט בצורה ספציפית, בזמן שהשני הוא העיצוב שיצורף לאובייקט של הוידג'ט [CLinkPager] שהמאפיין `skin` שלו מוגדר כ `classic`. לדוגמא, בקוד התצוגה הבאה, הוידג'ט הראשון משתמש בעיצוב `default` בזמן שהשני משתמש בעיצוב `classic`:

~~~
[php]
<?php $this->widget('CLinkPager'); ?>

<?php $this->widget('CLinkPager', array('skin'=>'classic')); ?>
~~~

אם ניצור וידג'ט עם כשאנו מגדירים את המאפיינים ההתחלתיים בקובץ התצוגה, מאפיינים אלו יתאחדו עם המאפיינים המוגדרים בעיצוב אך יקבלו עדיפות על פני אלו שהוגדרו בעיצוב. לדוגמא, הקוד הבא יוצר וידג'ט שמאפייניו ההתחלתיים יהיו

~~~
array('header'=>'', 'maxButtonCount'=>6, 'cssFile'=>false)
~~~

שהם התוצאה של איחוד המאפיינים ההתחלתיים שהוגדרו בקובץ התצוגה ובעיצוב `classic`.

~~~
[php]
<?php $this->widget('CLinkPager', array(
    'skin'=>'classic',
    'maxButtonCount'=>6,
    'cssFile'=>false,
)); ?>
~~~

יש לזכור שהשימוש בעיצובים אינו דורש שימוש בתבניות. למרות, בזמן השימוש בתבניות, המערכת תחפש את העיצובים תחת התיקיה `skins` של קבצי התצוגה של התבנית הפעילה (לדוגמא `WebRoot/themes/classic/views/skins`). במידה והעיצוב קיים בתיקית קבצי התצוגה של התבנית הפעילה ובתיקית קבצי התצוגה של האפליקציה, קבצי העיצוב הנמצאים תחת התבנית הפעילה יקלו עדיפות.

במידה והוידג'ט משתמש בעיצוב שאינו קיים, המערכת תיצור את הוידג'ט כרגיל ללא שום שגיאה.

> Info|מידע: שימוש בעיצובים יכול להשפיע לרעה על הביצועים של האפליקציה מאחר והמערכת צריכה לחפש את קובץ העיצוב בפעם הראשונה שהוידג'ט נוצר.

עיצוב הוא דומה להגדרות וידג'ט גלובאליות. ההבדלים העיקריים הם:

- עיצוב קשור יותר למאפיינים המייצגים תצוגה בוידג'ט;
- וידג'ט יכול להכיל מספר רב של עיצובים;
- ניתן להגדיר תבניות עבור עיצוב;
- שימוש בעיצוב יקר יותר מבחינת משאבים מאשר שימוש בהגדרות וידג'ט גלובאליות.

<div class="revision">$Id: topics.theming.txt 2172 2009-10-17 01:49:02Z qiang.xue $</div>